﻿namespace Auros.Categorisation.Samples.UserControls
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using umbraco.NodeFactory;
    using umbraco.presentation;

    public partial class RelatedPages : System.Web.UI.UserControl
    {
        private Node currentNode = null;

        /// <summary>
        /// Gets the current node.
        /// </summary>
        /// <value>The current node.</value>
        private Node CurrentNode
        {
            get
            {
                if (currentNode == null && UmbracoContext.Current.PageId.HasValue)
                    currentNode = new Node(UmbracoContext.Current.PageId.Value);

                return currentNode;
            }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            // quick and dirty query to get all related node IDs.
            // orders results by the number of shared categories and then by the creation date of the pages (newer pages with more shared categories at the top)
            var relatedNodes = this.GetRelatedNodeIDs()
                .OrderByDescending(n => n.Value)
                .ThenByDescending(n => new Node(n.Key).CreateDate)
                .Select(n => new Node(n.Key));

            this.PageList.DataSource = relatedNodes;
            this.PageList.DataBind();
        }

        /// <summary>
        /// Gets the related Node IDs with associated number of shared categories.
        /// </summary>
        private IEnumerable<KeyValuePair<int, int>> GetRelatedNodeIDs()
        {
            var currentPageProperty = CurrentNode.GetProperty("categories");

            int[] currentPageCategoryIds = null;

            if (currentPageProperty != null)
                currentPageCategoryIds = currentPageProperty.GetValueAsIntArray();

            if (currentPageCategoryIds != null)
            {
                // get nodes for entire website
                Node rootNode = new Node(-1);
                var nodes = rootNode.GetDescendantNodes();

                // for each descendant node get node ids for all nodes which share category ids with the current node.
                foreach (var node in nodes)
                {
                    var property = node.GetProperty("categories");

                    // if property is found and this node is not the Current Node.
                    if (property != null && node.Id != this.CurrentNode.Id)
                    {
                        // get category ids for this node
                        var nodeCategories = property.GetValueAsIntArray();

                        // get the number of same categories
                        int same = this.NoOfCommonCategories(currentPageCategoryIds, nodeCategories);

                        if (same > 0)
                            yield return new KeyValuePair<int, int>(node.Id, same);
                    }
                }
            }

            yield break;
        }

        /// <summary>
        /// Number of common IDs between two collections.
        /// </summary>
        private int NoOfCommonCategories(int[] nodeACategories, int[] nodeBCategories)
        {
            int count = 0;

            foreach (var item in nodeACategories)
            {
                if (nodeBCategories.Contains(item))
                    count++;
            }

            return count;
        }
    }
}